<script setup lang="ts">
	import {PropType, computed, nextTick, ref, watch} from 'vue';
	import _ from 'lodash';

	defineOptions({
		name: 'CustomMultipleSelectModal',
	});

	const props = defineProps({
		modelValue: {
			type: Array as PropType<Array<string>>,
			default: () => [],
		},
		title: {
			type: String,
			default: () => '请选择',
		},
		options: {
			type: Array as PropType<Array<{text: string; value: string}>>,
			default: () => [],
		},
	});

	const emits = defineEmits<{
		(e: 'update:modelValue', value: Array<string>): void;
	}>();

	// 弹出层组件实例
	const popupInstance = ref(null);

	// 选择器选中的值
	const _value = ref<Array<string>>([]);

	/**
	 * 选中的值对应的文本列表
	 */
	const selectValueTextList = ref<Array<string>>([]);

	/**
	 * 隐藏弹出层
	 */
	const hidePopup = () => {
		if (popupInstance.value) {
			popupInstance.value.close();
		}
	};

	/**
	 * 显示弹出层
	 */
	const showPopup = () => {
		if (popupInstance.value) {
			popupInstance.value.open();
		}
	};

	/**
	 * 选择点击事件
	 */
	const onSelectClick = () => {
		showPopup();
	};

	/**
	 * 填充渲染文本
	 */
	const fillRenderText = () => {
		selectValueTextList.value.length = 0;
		_value.value.forEach((value) => {
			const option = props.options.find((item) => item.value === value);
			if (option) {
				selectValueTextList.value.push(option.text);
			}
		});
	};

	/**
	 * 确定点击事件
	 */
	const onConfirm = () => {
		emits('update:modelValue', [..._value.value]);
		hidePopup();
		fillRenderText();
	};

	/**
	 * 选项点击事件
	 * @param {string} value - 选中的值
	 */
	const handleOptionClick = (value: string) => {
		if (_value.value.includes(value)) {
			_value.value = _value.value.filter((val) => val !== value);
		} else {
			_value.value.push(value);
		}
	};

	watch(
		() => props.modelValue,
		(value) => {
			if (value) {
				_value.value = value;
				fillRenderText();
			}
		},
		{immediate: true},
	);
</script>

<template>
	<view class="custom-multiple-select" @click="onSelectClick">
		<view class="label" v-if="selectValueTextList.length === 0">
			{{ props.title }}
		</view>
		<view class="value" v-else>{{ selectValueTextList.join('、') }}</view>
		<uni-icons type="down" size="14" color="gray"></uni-icons>
	</view>

	<uni-popup
		ref="popupInstance"
		type="bottom"
		:safe-area="false"
		:is-mask-click="false"
	>
		<view class="container">
			<view class="header">
				<view class="confirm-btn" @click="onConfirm">确定</view>
				<view class="title">{{ props.title }}</view>
				<view class="cancel-btn" @click="hidePopup">取消</view>
			</view>
			<view class="content">
				<view
					class="option"
					v-for="(option, optionIndex) in props.options"
					:key="optionIndex"
				>
					<radio
						:value="option.value"
						:checked="_value.includes(option.value)"
						@click="handleOptionClick(option.value)"
						:color="'#007cff'"
					/>
					<view class="label">{{ option.text }}</view>
				</view>
			</view>
		</view>
	</uni-popup>
</template>

<style scoped lang="scss">
	.custom-multiple-select {
		display: flex;
		column-gap: 12rpx;
		align-items: center;

		.label {
			color: gray;
		}

		.value {
			color: #333;
			font-size: 28rpx;
		}
	}

	.container {
		height: 65vh;
		display: flex;
		flex-direction: column;
		background-color: #fff;
		box-sizing: border-box;
		padding: 24rpx;
		row-gap: 24rpx;

		.header {
			display: flex;
			justify-content: space-between;
			align-items: center;
			box-sizing: border-box;

			.confirm-btn,
			.cancel-btn {
				font-size: 24rpx;
			}

			.confirm-btn {
				color: #007cff;
			}

			.cancel-btn {
				color: gray;
			}

			.title {
				font-weight: bold;
				font-size: 32rpx;
				color: #000;
			}
		}

		.content {
			flex: 1;
			height: 0;
			box-sizing: border-box;
			overflow-y: auto;
			display: flex;
			flex-direction: column;
			row-gap: 16rpx;

			.option {
				display: flex;
				font-size: 28rpx;
				align-items: center;
				height: 64rpx;
				column-gap: 12rpx;

				.label {
					height: 100%;
					display: flex;
					align-items: center;
					color: #000;
				}
			}
		}

		.footer {
			padding: 24rpx 24rpx 48rpx 24rpx;

			.btn {
				width: 100%;
				height: 64rpx;
				background-color: #007cff;
				display: flex;
				align-items: center;
				justify-content: center;
				color: #fff;
				font-size: 24rpx;
				border-radius: 8rpx;
			}
		}
	}
</style>
